package com.zjlab.sandtable.handler;

import cn.hutool.core.util.ObjectUtil;
import com.zjlab.sandtable.bean.Info;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author xue
 * @create 2022-11-07 14:45
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class SandTableUdpHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        ByteBuf content = msg.content();
        if (content.readableBytes() < 5) {
            log.warn("消息长度不够");
            return;
        }
        int len = 0;
        if (Info.MAGIC != content.getByte(0) | (len = content.getShort(1)) != content.readableBytes()) {
            log.warn("消息头不正确或者长度不正确，检测的消息长度为：{}", len);
            return;
        }
        content.skipBytes(3);
        int infoByte = content.readShort();
        Class<? extends Info> infoClass = Info.getInfoClass(infoByte);
        if (ObjectUtil.isNull(infoClass)) {
            log.warn("消息类型是未协商的,10进制表示为：" + infoByte);
            return;
        }

        Method method = infoClass.getMethod("decoding", ByteBuf.class);
        Info info = (Info) method.invoke(infoClass.newInstance(), content);

        ctx.fireChannelRead(info);
    }
}
